package com.test.aop;

import java.lang.reflect.Method;

/**
 * ReflectiveMethodInvocation类实现了MethodInvocation接口，用于通过反射调用方法
 * 它封装了目标对象、方法和参数，提供方法调用的相关信息和能力
 */
public class ReflectiveMethodInvocation implements MethodInvocation{

    // 目标对象，即方法所属的实例
    protected final Object target;

    // 要调用的方法
    protected final Method method;

    // 方法的参数
    protected final Object[] arguments;

    /**
     * 构造方法，初始化ReflectiveMethodInvocation对象
     *
     * @param target 目标对象，即方法所属的实例
     * @param method 要调用的方法
     * @param arguments 方法的参数
     */
    public ReflectiveMethodInvocation (Object target, Method method, Object[] arguments) {
        this.target = target;
        this.method = method;
        this.arguments = arguments;
    }

    /**
     * 获取要调用的方法
     *
     * @return 要调用的方法对象
     */
    @Override
    public Method getMethod() {
        return method;
    }

    /**
     * 获取方法的参数
     *
     * @return 方法的参数数组
     */
    @Override
    public Object[] getArguments() {
        return arguments;
    }

    /**
     * 获取目标对象，即方法所属的实例
     *
     * @return 目标对象
     */
    @Override
    public Object getThis() {
        return target;
    }

    /**
     * 执行方法调用，这是MethodInvocation接口规定的行为
     *
     * @return 方法调用的结果
     * @throws Throwable 方法调用过程中可能抛出的异常
     */
    @Override
    public Object proceed() throws Throwable {
        return invokeJoinPoint();
    }

    /**
     * 通过反射机制调用实际的方法，这是核心的逻辑
     * 如果方法不可访问，会临时修改其访问权限以完成调用
     *
     * @return 方法调用的结果
     * @throws Throwable 方法调用过程中可能抛出的异常
     */
    protected Object invokeJoinPoint() throws Throwable {
        if (!method.isAccessible()){
            method.setAccessible(true);
        }
        return method.invoke(target, arguments);
    }
}
